# 版本: 1.0.0
# 作者: 陈振玺
# 功能: 文件管理器模块

import os
import shutil
from datetime import datetime
from pathlib import Path
import logging
from typing import Optional


class FileManager:
    """
    文件管理器类
    
    提供文件拷贝、管理功能，支持时间戳子目录
    
    版本: 1.0.0
    作者: 陈振玺
    """
    
    def __init__(self, base_dir: str = None, server_host: str = "192.168.10.98", server_port: int = 2121):
        """
        初始化文件管理器
        
        Args:
            base_dir (str): 基础目录路径，默认为当前目录下的www文件夹
            server_host (str): 服务器主机地址
            server_port (int): 服务器端口
        """
        self.base_dir = base_dir or os.path.join(os.getcwd(), "www")
        self.server_host = server_host
        self.server_port = server_port
        
        # 确保基础目录存在
        os.makedirs(self.base_dir, exist_ok=True)
        
        # 配置日志
        self.logger = logging.getLogger(__name__)
    
    def _generate_timestamp_dir(self) -> str:
        """
        生成时间戳目录名
        
        Returns:
            str: 格式为YYYYMMDD_HHMMSS的时间戳字符串
        """
        now = datetime.now()
        return now.strftime("%Y%m%d_%H%M%S")
    
    def copy_file(self, source_path: str, custom_subdir: str = None) -> str:
        """
        拷贝文件到服务目录
        
        Args:
            source_path (str): 源文件路径
            custom_subdir (str): 自定义子目录名，如果不提供则使用时间戳
        
        Returns:
            str: 文件的访问URL
        
        Raises:
            FileNotFoundError: 源文件不存在
            PermissionError: 权限不足
            OSError: 其他文件操作错误
        """
        if not os.path.exists(source_path):
            raise FileNotFoundError(f"源文件不存在: {source_path}")
        
        if not os.path.isfile(source_path):
            raise ValueError(f"路径不是文件: {source_path}")
        
        # 生成子目录名
        subdir_name = custom_subdir or self._generate_timestamp_dir()
        target_dir = os.path.join(self.base_dir, subdir_name)
        
        # 创建目标目录
        os.makedirs(target_dir, exist_ok=True)
        
        # 获取文件名
        filename = os.path.basename(source_path)
        target_path = os.path.join(target_dir, filename)
        
        try:
            # 拷贝文件
            shutil.copy2(source_path, target_path)
            self.logger.info(f"文件已拷贝: {source_path} -> {target_path}")
            
            # 生成访问URL
            relative_path = os.path.join(subdir_name, filename).replace("\\", "/")
            url = f"http://{self.server_host}:{self.server_port}/files/{relative_path}"
            
            return url
            
        except Exception as e:
            self.logger.error(f"文件拷贝失败: {e}")
            raise
    
    def copy_directory(self, source_dir: str, custom_subdir: str = None) -> str:
        """
        拷贝整个目录到服务目录
        
        Args:
            source_dir (str): 源目录路径
            custom_subdir (str): 自定义子目录名，如果不提供则使用时间戳
        
        Returns:
            str: 目录的访问URL
        
        Raises:
            FileNotFoundError: 源目录不存在
            PermissionError: 权限不足
            OSError: 其他文件操作错误
        """
        if not os.path.exists(source_dir):
            raise FileNotFoundError(f"源目录不存在: {source_dir}")
        
        if not os.path.isdir(source_dir):
            raise ValueError(f"路径不是目录: {source_dir}")
        
        # 生成子目录名
        subdir_name = custom_subdir or self._generate_timestamp_dir()
        target_dir = os.path.join(self.base_dir, subdir_name)
        
        try:
            # 拷贝整个目录
            shutil.copytree(source_dir, target_dir, dirs_exist_ok=True)
            self.logger.info(f"目录已拷贝: {source_dir} -> {target_dir}")
            
            # 生成访问URL
            url = f"http://{self.server_host}:{self.server_port}/list/{subdir_name}"
            
            return url
            
        except Exception as e:
            self.logger.error(f"目录拷贝失败: {e}")
            raise
    
    def create_html_file(self, content: str, filename: str = None, custom_subdir: str = None) -> str:
        """
        创建HTML文件并返回访问URL
        
        Args:
            content (str): HTML内容
            filename (str): 文件名，默认为index.html
            custom_subdir (str): 自定义子目录名，如果不提供则使用时间戳
        
        Returns:
            str: HTML文件的访问URL
        """
        filename = filename or "index.html"
        if not filename.endswith('.html'):
            filename += '.html'
        
        # 生成子目录名
        subdir_name = custom_subdir or self._generate_timestamp_dir()
        target_dir = os.path.join(self.base_dir, subdir_name)
        
        # 创建目标目录
        os.makedirs(target_dir, exist_ok=True)
        
        # 创建HTML文件
        target_path = os.path.join(target_dir, filename)
        
        try:
            with open(target_path, 'w', encoding='utf-8') as f:
                f.write(content)
            
            self.logger.info(f"HTML文件已创建: {target_path}")
            
            # 生成访问URL
            relative_path = os.path.join(subdir_name, filename).replace("\\", "/")
            url = f"http://{self.server_host}:{self.server_port}/files/{relative_path}"
            
            return url
            
        except Exception as e:
            self.logger.error(f"HTML文件创建失败: {e}")
            raise
    
    def list_files(self, subdir: str = "") -> list:
        """
        列出指定子目录中的文件
        
        Args:
            subdir (str): 子目录名，空字符串表示根目录
        
        Returns:
            list: 文件和目录信息列表
        """
        target_dir = os.path.join(self.base_dir, subdir) if subdir else self.base_dir
        
        if not os.path.exists(target_dir):
            return []
        
        items = []
        try:
            for item in os.listdir(target_dir):
                item_path = os.path.join(target_dir, item)
                is_dir = os.path.isdir(item_path)
                
                relative_path = os.path.join(subdir, item).replace("\\", "/") if subdir else item
                
                items.append({
                    "name": item,
                    "type": "directory" if is_dir else "file",
                    "path": relative_path,
                    "url": f"http://{self.server_host}:{self.server_port}/files/{relative_path}" if not is_dir else None
                })
        except PermissionError:
            self.logger.error(f"权限不足，无法访问目录: {target_dir}")
        
        return items
    
    def delete_file(self, relative_path: str) -> bool:
        """
        删除文件或目录
        
        Args:
            relative_path (str): 相对于基础目录的路径
        
        Returns:
            bool: 删除是否成功
        """
        target_path = os.path.join(self.base_dir, relative_path)
        
        if not os.path.exists(target_path):
            self.logger.warning(f"文件或目录不存在: {target_path}")
            return False
        
        try:
            if os.path.isfile(target_path):
                os.remove(target_path)
                self.logger.info(f"文件已删除: {target_path}")
            elif os.path.isdir(target_path):
                shutil.rmtree(target_path)
                self.logger.info(f"目录已删除: {target_path}")
            
            return True
            
        except Exception as e:
            self.logger.error(f"删除失败: {e}")
            return False
    
    def get_file_url(self, relative_path: str) -> str:
        """
        获取文件的访问URL
        
        Args:
            relative_path (str): 相对于基础目录的文件路径
        
        Returns:
            str: 文件访问URL
        """
        # 确保路径使用正斜杠
        relative_path = relative_path.replace("\\", "/")
        if relative_path.startswith("/"):
            relative_path = relative_path[1:]
        
        return f"http://{self.server_host}:{self.server_port}/files/{relative_path}"